//
// Created by pzw on 24-2-22.
//

#include <cstring>
#include "file_dir.h"
#include "file_syscall.h"

int file_dir::file_dir_chmod(const char *path, mode_t mode) {
    return chmod(path, mode);
}

int file_dir::file_dir_chown(const char *path, uid_t owner, gid_t group) {
    return chown(path, owner, group);
}

int file_dir::file_dir_unlink(const char *path) {
    return unlink(path);
}

int file_dir::file_dir_link(const char *path1, const char *path2) {
    return link(path1, path2);
}

int file_dir::file_dir_symlink(const char *path1, const char *path2) {
    return symlink(path1, path2);
}

int file_dir::file_dir_mkdir(const char *path, mode_t mode) {
    return mkdir(path, mode);
}

int file_dir::file_dir_rmdir(const char *path) {
    return rmdir(path);
}

int file_dir::file_dir_chdir(const char *path) {
    return chdir(path);
}

char *file_dir::file_dir_getcwd(char *buf, size_t size) {
    return getcwd(buf, size);
}

DIR *file_dir::file_dir_opendir(const char *name) {
    return opendir(name);
}

struct dirent *file_dir::file_dir_readdir(DIR *dirp) {
    return readdir(dirp);
}

long int file_dir::file_dir_telldir(DIR *dirp) {
    return telldir(dirp);
}

void file_dir::file_dir_seekdir(DIR *dirp, long loc) {
    seekdir(dirp, loc);
}

int file_dir::file_dir_closedir(DIR *dirp) {
    return closedir(dirp);
}

void printdir(char *dir, int depth) {
    DIR *dp;
    struct dirent *entry;
    struct stat statbuf;
    file_dir file_dir{};
    file_syscall file_syscall{};

    if ((dp = file_dir.file_dir_opendir(dir)) == nullptr) {
        fprintf(stderr, "cannot open dir: %s\n", dir);
        return;
    }

    file_dir.file_dir_chdir(dir);
    while ((entry = file_dir.file_dir_readdir(dp)) != nullptr) {
        file_syscall.file_sys_lstat(entry->d_name, &statbuf);
        if (S_ISDIR(statbuf.st_mode)) {
            /* Found a dir, but ignore . and .. */
            if (strcmp(".", entry->d_name) == 0
                || strcmp("..", entry->d_name) == 0) {
                continue;
            }
            printf("%*s/\n", depth, " ", entry->d_name);
            /* Recurse at a new indent level */
            printdir(entry->d_name, depth + 4);
        } else {
            printf("%*s%s\n", depth, " ", entry->d_name);
        }
    }

    file_dir.file_dir_chdir("..");
    file_dir.file_dir_closedir(dp);
}

int file_dir_main() {
    printf("Dir scan of /home: \n");
    printdir("/home", 0);
    printf("done. \n");
    return 0;
}
